﻿using System;
using System.Collections.Generic;

namespace Bogus
{
   /// <summary>
   /// Represents a Faker rule
   /// </summary>
   public class Rule<T>
   {
      /// <summary>
      /// Populate action
      /// </summary>
      public T Action { get; set; }

      /// <summary>
      /// Property name, maybe null for finalize or create.
      /// </summary>
      public string PropertyName { get; set; }

      /// <summary>
      /// The rule set this rule belongs to.
      /// </summary>
      public string RuleSet { get; set; } = string.Empty;

      /// <summary>
      /// Prohibits the rule from being applied in strict mode.
      /// </summary>
      public bool ProhibitInStrictMode { get; set; } = false;
   }

   public class PopulateAction<T> : Rule<Func<Faker, T, object>>
   {
   }

   public class FinalizeAction<T> : Rule<Action<Faker, T>>
   {
   }

   public class MultiDictionary<Key, Key2, Value> : Dictionary<Key, Dictionary<Key2, Value>>
   {
      public MultiDictionary(IEqualityComparer<Key> comparer) : base(comparer)
      {
      }

      public void Add(Key key, Key2 key2, Value value)
      {
         if( !this.TryGetValue(key, out var values) )
         {
            values = new Dictionary<Key2, Value>();
            this.Add(key, values);
         }
         values[key2] = value;
      }
   }

   public class MultiSetDictionary<Key, Value> : Dictionary<Key, HashSet<Value>>
   {
      public MultiSetDictionary(IEqualityComparer<Key> comparer) : base(comparer)
      {
      }

      public void Add(Key key, Value value)
      {
         if( !this.TryGetValue(key, out var values) )
         {
            values = new HashSet<Value>();
            this.Add(key, values);
         }
         if( values.Contains(value) )
            throw new ArgumentException("An item with the same key has already been added.");
         values.Add(value);
      }
   }
}